/*
 *      SymTable.java
 *
 *      Copyright 2008 Pablo Nicolas Diaz Bilotto <pablonicolas.diaz@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
package symbolStorageService;

import java.util.Hashtable;
import java.util.Map.Entry;

import lexer.EntryType;
import lexer.token.TokenEnum;
import errorService.IErrorReporter;


/**
 * The Class SymTable.
 */
public class SymTable extends Hashtable<String, ISymEntry> implements ISymTable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 5629779332415445281L;

	/**
	 * Instantiates a new sym table.
	 */
	public SymTable() {
		super();
		this.put("_if", new SymEntry(0, TokenEnum.IF, EntryType.NOTYPE, true));
		this.put("_int", new SymEntry(0, TokenEnum.INT, EntryType.INT, true));
		this.put("_else", new SymEntry(0, TokenEnum.ELSE, EntryType.NOTYPE,	true));
		this.put("_print", new SymEntry(0, TokenEnum.PRINT, EntryType.STRING,true));
		this.put("_double", new SymEntry(0, TokenEnum.DOUBLE, EntryType.DOUBLE,	true));
		this.put("_todouble", new SymEntry(0, TokenEnum.TO_DOUBLE,EntryType.DOUBLE, true));
		this.put("_toint", new SymEntry(0, TokenEnum.TO_INT, EntryType.INT,true));
		this.put("_do", new SymEntry(0, TokenEnum.DO, EntryType.NOTYPE, true));
		this.put("_until", new SymEntry(0, TokenEnum.UNTIL, EntryType.NOTYPE,true));
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seesymbol_storage_service.ISymTable#InformAnormalSymbols(errorService.
	 * IErrorReporter)
	 */
	public final void informAnormalSymbols(final IErrorReporter t) {

		for (Entry<String, ISymEntry> i : this.entrySet()) {
			if (i.getValue().getKind() == TokenEnum.IDENTIFIER) {
				if (!i.getValue().isTyped()) {
					t.reportError(i.getValue().getLineNumber(),"ICG : "+ i.getKey()
							.toString().substring(1)
							+ " => " + "No esta declarada");
				} else if (!i.getValue().isUsed()) {
					t.reportWarning(i.getValue().getLineNumber(),"ICG : "+ i.getKey()
							.toString().substring(1)
							+ " => " + "No esta usada");
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.AbstractMap#toString()
	 */
	@Override
	public String toString() {
		StringBuffer str = new StringBuffer();
		for (Entry<String, ISymEntry> i : this.entrySet()) {
			if (!((i.getValue().getKind().equals(TokenEnum.CONSTANT)
					&& i.getValue().getType()==EntryType.INT)
					|| i.getValue().isKeyword() || (!i.getValue().isTyped())))
			str.append("\t" + i.getKey() + " " + i.getValue() + "\n");
		}
		return str.toString();
	}

}
